#include "VisiyunDevice.h"
#include "CameraSDKInterface.h"
#include <QDebug>
#include <QImage>
#include <QThread>

/**
 * @brief VisiyunDevice构造函数，初始化设备连接参数
 * @param deviceIp 设备IP地址
 * @param parent 父对象指针，用于内存管理
 */
VisiyunDevice::VisiyunDevice(const QString& deviceIp, QObject *parent)
    : QObject(parent), m_deviceIp(deviceIp), m_controlId(-1),
      m_isConnected(false), m_running(false), m_pRawBuf(nullptr),
      m_timeUnit(0), m_gainUnit(0), m_frequencyUnit(0),
      m_minGain(0.0), m_maxGain(100.0), m_minFrequency(1.0), m_maxFrequency(10000.0),
      m_minExposureTime(1), m_maxExposureTime(1000000000),m_TriggerMode(TRIGGER_MODE_CONTINUOUS),m_ExternalTriggerChannel(1),m_TriggerEdgeType(0)
{
    m_BeatheartTimer.setInterval(5000);
    connect(&m_BeatheartTimer, &QTimer::timeout, this, &VisiyunDevice::sendBeatheart);   
}

/**
 * @brief VisiyunDevice析构函数，释放资源并关闭连接
 */
VisiyunDevice::~VisiyunDevice()
{
    stopCapture();
    if (m_isConnected) {
        close();
    }
    delete[] m_pRawBuf;
}

/**
 * @brief 打开设备连接
 * @return 成功返回true，失败返回false
 */
bool VisiyunDevice::open()
{
    if (m_isConnected) {
        qWarning() << "Device already connected:" << m_deviceIp;
        return true;
    }
    // 打开设备连接
    m_controlId = VsyCam_OpenConnection(m_deviceIp.toLatin1().data(), 8886);
    if (m_controlId <= 0) {
        qWarning() << "Failed to open device:" << m_deviceIp;
        return false;
    }
    int colorValue = VsyCam_ReadCameraParam(m_controlId, COLOR);
    int syncValue = VsyCam_ReadCameraParam(m_controlId, SYNC);
    qDebug()<<"COLOR:"<<colorValue<<"SYNC:"<<syncValue;
    //设置数据格式灰度
    int result = VsyCam_UpdateCameraParam(m_controlId, COLOR, 0,nullptr);
    if (result != VsyCam_SUCCESS) {
        qWarning() << "Failed to set COLOR value for device:" << m_deviceIp;
        return false;
    }
    result = VsyCam_UpdateCameraParam(m_controlId, TRI_PARAM_EN, 0,nullptr);
    if (result != VsyCam_SUCCESS) {
        qWarning() << "Failed to set TRI_PARAM_EN value for device:" << m_deviceIp;
        return false;
    }
    if (0 != setTriggerMode(m_TriggerMode)) {
        qWarning() << "Failed to set SYNC value for device:" << m_deviceIp;
        return false;
    }

    m_isConnected = true;
    qInfo() << "Device connected successfully:" << m_deviceIp;
    
    // 初始化设备参数范围和单位
    if (!initializeDeviceParameters()) {
        qWarning() << "Failed to initialize device parameters for:" << m_deviceIp;
    }
    m_BeatheartTimer.start();
    return true;
}

/**
 * @brief 获取设备曝光时间单位
 * @return 时间单位值 (0:纳秒, 1:微秒, 2:毫秒, 3:秒)
 */
int VisiyunDevice::getTimeUnit() const
{
    return m_timeUnit;
}

/**
 * @brief 获取设备增益单位
 * @return 增益单位值
 */
int VisiyunDevice::getGainUnit() const
{
    return m_gainUnit;
}

/**
 * @brief 获取设备采样频率单位
 * @return 频率单位值
 */
int VisiyunDevice::getFrequencyUnit() const
{
    return m_frequencyUnit;
}

/**
 * @brief 设置设备曝光时间单位
 * @param unit 时间单位值 (0:纳秒, 1:微秒, 2:毫秒, 3:秒)
 * @return 操作结果，0表示成功，其他表示失败
 */
int VisiyunDevice::setTimeUnit(int unit)
{
    if (!m_isConnected || m_controlId <= 0) {
        qWarning() << "Device not connected when setting time unit:" << m_deviceIp;
        return -1;
    }

    // 验证单位值是否有效
    if (unit < 0 || unit > 3) {
        qWarning() << "Invalid time unit:" << unit << " for device:" << m_deviceIp;
        return -2;
    }

    // 先更新设备参数
    int result = VsyCam_UpdateCameraParam(m_controlId, TIME_UNIT, unit, nullptr);
    if (result != VsyCam_SUCCESS) {
        qWarning() << "Failed to set time unit for device:" << m_deviceIp;
        return -1;
    }

    // 更新本地成员变量
    m_timeUnit = unit;
    qInfo() << "Time unit set to" << unit << "for device:" << m_deviceIp;
    
    return 0;
}

/**
 * @brief 设置设备增益单位
 * @param unit 增益单位值
 * @return 操作结果，0表示成功，其他表示失败
 */
int VisiyunDevice::setGainUnit(int unit)
{
    if (!m_isConnected || m_controlId <= 0) {
        qWarning() << "Device not connected when setting gain unit:" << m_deviceIp;
        return -1;
    }

    // 先更新设备参数
    int result = VsyCam_UpdateCameraParam(m_controlId, GAIN_UNIT, unit, nullptr);
    if (result != VsyCam_SUCCESS) {
        qWarning() << "Failed to set gain unit for device:" << m_deviceIp;
        return -1;
    }

    // 更新本地成员变量
    m_gainUnit = unit;
    qInfo() << "Gain unit set to" << unit << "for device:" << m_deviceIp;
    
    return 0;
}

/**
 * @brief 设置设备采样频率单位
 * @param unit 频率单位值
 * @return 操作结果，0表示成功，其他表示失败
 */
int VisiyunDevice::setFrequencyUnit(int unit)
{
    if (!m_isConnected || m_controlId <= 0) {
        qWarning() << "Device not connected when setting frequency unit:" << m_deviceIp;
        return -1;
    }

    // 先更新设备参数
    int result = VsyCam_UpdateCameraParam(m_controlId, FREQ_UNIT, unit, nullptr);
    if (result != VsyCam_SUCCESS) {
        qWarning() << "Failed to set frequency unit for device:" << m_deviceIp;
        return -1;
    }

    // 更新本地成员变量
    m_frequencyUnit = unit;
    qInfo() << "Frequency unit set to" << unit << "for device:" << m_deviceIp;
    
    return 0;
}

/**
 * @brief 获取设备增益最小值
 * @return 增益最小值
 */
quint64 VisiyunDevice::getMinGain() const
{
    return m_minGain;
}

/**
 * @brief 获取设备增益最大值
 * @return 增益最大值
 */
quint64 VisiyunDevice::getMaxGain() const
{
    return m_maxGain;
}

/**
 * @brief 获取设备采样频率最小值
 * @return 采样频率最小值 (Hz)
 */
quint64 VisiyunDevice::getMinFrequency() const
{
    return m_minFrequency;
}

/**
 * @brief 获取设备采样频率最大值
 * @return 采样频率最大值 (Hz)
 */
quint64 VisiyunDevice::getMaxFrequency() const
{
    return m_maxFrequency;
}

/**
 * @brief 获取设备曝光时间最小值
 * @return 曝光时间最小值 (纳秒)
 */
quint64 VisiyunDevice::getMinExposureTime() const
{
    return m_minExposureTime;
}

/**
 * @brief 获取设备曝光时间最大值
 * @return 曝光时间最大值 (纳秒)
 */
quint64 VisiyunDevice::getMaxExposureTime() const
{
    return m_maxExposureTime;
}

/**
 * @brief 设置设备增益最小值
 * @param min 增益最小值
 * @return 操作结果，0表示成功，其他表示失败
 */
int VisiyunDevice::setMinGain(quint64 min)
{
    if (!m_isConnected || m_controlId <= 0) {
        qWarning() << "Device not connected when setting min gain:" << m_deviceIp;
        return -1;
    }

    // 验证最小值是否小于当前最大值
    if (min >= m_maxGain) {
        qWarning() << "Min gain must be less than max gain (" << m_maxGain << ") for device:" << m_deviceIp;
        return -2;
    }

    // 先更新设备参数
    int result = VsyCam_UpdateCameraParam(m_controlId, MIN_GAIN, static_cast<int>(min), nullptr);
    if (result != VsyCam_SUCCESS) {
        qWarning() << "Failed to set min gain for device:" << m_deviceIp;
        return -1;
    }

    // 更新本地成员变量
    m_minGain = min;
    qInfo() << "Min gain set to" << min << "for device:" << m_deviceIp;
    
    return 0;
}

/**
 * @brief 设置设备增益最大值
 * @param max 增益最大值
 * @return 操作结果，0表示成功，其他表示失败
 */
int VisiyunDevice::setMaxGain(quint64 max)
{
    if (!m_isConnected || m_controlId <= 0) {
        qWarning() << "Device not connected when setting max gain:" << m_deviceIp;
        return -1;
    }

    // 验证最大值是否大于当前最小值
    if (max <= m_minGain) {
        qWarning() << "Max gain must be greater than min gain (" << m_minGain << ") for device:" << m_deviceIp;
        return -2;
    }

    // 先更新设备参数
    int result = VsyCam_UpdateCameraParam(m_controlId, MAX_GAIN, static_cast<int>(max), nullptr);
    if (result != VsyCam_SUCCESS) {
        qWarning() << "Failed to set max gain for device:" << m_deviceIp;
        return -1;
    }

    // 更新本地成员变量
    m_maxGain = max;
    qInfo() << "Max gain set to" << max << "for device:" << m_deviceIp;
    
    return 0;
}

/**
 * @brief 设置设备采样频率最小值
 * @param min 采样频率最小值 (Hz)
 * @return 操作结果，0表示成功，其他表示失败
 */
int VisiyunDevice::setMinFrequency(quint64 min)
{
    if (!m_isConnected || m_controlId <= 0) {
        qWarning() << "Device not connected when setting min frequency:" << m_deviceIp;
        return -1;
    }

    // 验证最小值是否小于当前最大值
    if (min >= m_maxFrequency) {
        qWarning() << "Min frequency must be less than max frequency (" << m_maxFrequency << ") for device:" << m_deviceIp;
        return -2;
    }

    // 先更新设备参数
    int result = VsyCam_UpdateCameraParam(m_controlId, MIN_FREQ, static_cast<int>(min), nullptr);
    if (result != VsyCam_SUCCESS) {
        qWarning() << "Failed to set min frequency for device:" << m_deviceIp;
        return -1;
    }

    // 更新本地成员变量
    m_minFrequency = min;
    qInfo() << "Min frequency set to" << min << "Hz for device:" << m_deviceIp;
    
    return 0;
}

/**
 * @brief 设置设备采样频率最大值
 * @param max 采样频率最大值 (Hz)
 * @return 操作结果，0表示成功，其他表示失败
 */
int VisiyunDevice::setMaxFrequency(quint64 max)
{
    if (!m_isConnected || m_controlId <= 0) {
        qWarning() << "Device not connected when setting max frequency:" << m_deviceIp;
        return -1;
    }

    // 验证最大值是否大于当前最小值
    if (max <= m_minFrequency) {
        qWarning() << "Max frequency must be greater than min frequency (" << m_minFrequency << ") for device:" << m_deviceIp;
        return -2;
    }

    // 先更新设备参数
    int result = VsyCam_UpdateCameraParam(m_controlId, MAX_FREQ, static_cast<int>(max), nullptr);
    if (result != VsyCam_SUCCESS) {
        qWarning() << "Failed to set max frequency for device:" << m_deviceIp;
        return -1;
    }

    // 更新本地成员变量
    m_maxFrequency = max;
    qInfo() << "Max frequency set to" << max << "Hz for device:" << m_deviceIp;
    
    return 0;
}

/**
 * @brief 设置设备曝光时间最小值
 * @param min 曝光时间最小值 (纳秒)
 * @return 操作结果，0表示成功，其他表示失败
 */
int VisiyunDevice::setMinExposureTime(quint64 min)
{
    if (!m_isConnected || m_controlId <= 0) {
        qWarning() << "Device not connected when setting min exposure time:" << m_deviceIp;
        return -1;
    }

    // 验证最小值是否小于当前最大值
    if (min >= m_maxExposureTime) {
        qWarning() << "Min exposure time must be less than max exposure time (" << m_maxExposureTime << ") ns for device:" << m_deviceIp;
        return -2;
    }

    // 根据当前时间单位将纳秒转换为相应单位的值
    int minTimeValue;
    switch(m_timeUnit) {
        case 0: // 纳秒
            minTimeValue = static_cast<int>(min);
            break;
        case 1: // 微秒
            minTimeValue = static_cast<int>(min / 1000);
            break;
        case 2: // 毫秒
            minTimeValue = static_cast<int>(min / 1000000);
            break;
        case 3: // 秒
            minTimeValue = static_cast<int>(min / 1000000000);
            break;
        default:
            qWarning() << "Unknown exposure unit:" << m_timeUnit << " for device:" << m_deviceIp;
            return -1;
    }

    // 先更新设备参数
    int result = VsyCam_UpdateCameraParam(m_controlId, MIN_TIME, minTimeValue, nullptr);
    if (result != VsyCam_SUCCESS) {
        qWarning() << "Failed to set min exposure time for device:" << m_deviceIp;
        return -1;
    }

    // 更新本地成员变量
    m_minExposureTime = min;
    qInfo() << "Min exposure time set to" << min << "ns for device:" << m_deviceIp;
    
    return 0;
}

/**
 * @brief 设置设备曝光时间最大值
 * @param max 曝光时间最大值 (纳秒)
 * @return 操作结果，0表示成功，其他表示失败
 */
int VisiyunDevice::setMaxExposureTime(quint64 max)
{
    if (!m_isConnected || m_controlId <= 0) {
        qWarning() << "Device not connected when setting max exposure time:" << m_deviceIp;
        return -1;
    }

    // 验证最大值是否大于当前最小值
    if (max <= m_minExposureTime) {
        qWarning() << "Max exposure time must be greater than min exposure time (" << m_minExposureTime << ") ns for device:" << m_deviceIp;
        return -2;
    }

    // 根据当前时间单位将纳秒转换为相应单位的值
    int maxTimeValue;
    switch(m_timeUnit) {
        case 0: // 纳秒
            maxTimeValue = static_cast<int>(max);
            break;
        case 1: // 微秒
            maxTimeValue = static_cast<int>(max / 1000);
            break;
        case 2: // 毫秒
            maxTimeValue = static_cast<int>(max / 1000000);
            break;
        case 3: // 秒
            maxTimeValue = static_cast<int>(max / 1000000000);
            break;
        default:
            qWarning() << "Unknown exposure unit:" << m_timeUnit << " for device:" << m_deviceIp;
            return -1;
    }

    // 先更新设备参数
    int result = VsyCam_UpdateCameraParam(m_controlId, MAX_TIME, maxTimeValue, nullptr);
    if (result != VsyCam_SUCCESS) {
        qWarning() << "Failed to set max exposure time for device:" << m_deviceIp;
        return -1;
    }

    // 更新本地成员变量
    m_maxExposureTime = max;
    qInfo() << "Max exposure time set to" << max << "ns for device:" << m_deviceIp;
    
    return 0;
}

/**
 * @brief 关闭设备连接
 */
void VisiyunDevice::close()
{
    if (!m_isConnected || m_controlId <= 0) {
        return;
    }
    
    stopCapture();
    m_BeatheartTimer.stop();
    // 关闭设备连接
    VsyCam_CloseConnection(m_controlId);
    m_controlId = -1;
    m_isConnected = false;
    qInfo() << "Device disconnected:" << m_deviceIp;
    emit connectionStateChanged(false);
}

/**
 * @brief 设置图像采集回调函数
 * @param callback 回调函数，当图像采集完成时调用
 */
void VisiyunDevice::setImageCallback(ImageCallback callback)
{
    QMutexLocker locker(&m_mutex);
    m_callback = callback;
}

/**
 * @brief 启动图像采集线程
 * @return 成功返回true，失败返回false
 */
bool VisiyunDevice::startCapture()
{
    if (!m_isConnected) {
        qWarning() << "Cannot start capture - device not properly connected:" << m_deviceIp;
        return false;
    }

    if (m_running) {
        return true; // 已经在运行中
    }
    //初始化参数
    int width = VsyCam_ReadCameraParam(m_controlId,WIDTH);//图像宽
    int hight = VsyCam_ReadCameraParam(m_controlId,HEIGHT);//图像高
    m_pRawBuf = new quint8[width * hight*2];
    // 初始化图像缓冲区
    if (!m_pRawBuf||!(width&hight)) {
       return false;
    }
    m_imageTransId= VsyCam_OpenConnection(m_deviceIp.toLatin1().data(),8888);
    m_running = true;
    m_captureFuture = QtConcurrent::run(this, &VisiyunDevice::captureImages);
    connect(&m_captureWatcher, &QFutureWatcher<void>::finished, this, [this]() {
        delete []m_pRawBuf;
        m_pRawBuf=nullptr;
        qDebug() << "Capture finished for device:" << m_deviceIp;
    });
    m_captureWatcher.setFuture(m_captureFuture);

    return true;
}

/**
 * @brief 停止图像采集线程
 */
void VisiyunDevice::stopCapture()
{
    if (!m_running) return;
    m_running = false;
    m_captureWatcher.waitForFinished();
    VsyCam_CloseConnection(m_imageTransId);
    if(m_pRawBuf)
    {
        delete[] m_pRawBuf;
        m_pRawBuf=nullptr;
    }
}

/**
 * @brief 图像采集线程主函数
 * 循环获取图像数据并通过回调函数和信号通知上层
 */
void VisiyunDevice::captureImages()
{
    int ret = -1;
    int camVersion = VsyCam_ReadCameraParam(m_controlId,FIRMWARE_VERSION);//相机固件版本
    //初始化参数
    int width = VsyCam_ReadCameraParam(m_controlId,WIDTH);//图像宽
    int hight = VsyCam_ReadCameraParam(m_controlId,HEIGHT);//图像高
    FRAME_HEADER header;
    while (m_running)
    {
        ret = VsyCam_GetImage(m_imageTransId, & header, m_pRawBuf, camVersion);
        if (VsyCam_SUCCESS != ret)
        {
            continue;
        }
        QMutexLocker locker(&m_mutex);
        if (m_callback)
        {
            QImage image(m_pRawBuf, width, hight, QImage::Format_Grayscale16);
            m_callback(m_deviceIp, image, m_TriggerMode);
        }
    }
    qDebug()<<"captureImage Finish";
}

/**
 * @brief 获取当前曝光时间
 * @return 曝光时间(纳秒)，失败返回-1
 */
quint64 VisiyunDevice::getExposureTime() const
{
    if (!m_isConnected || m_controlId <= 0) {
        qWarning() << "Device not connected:" << m_deviceIp;
        return -1;
    }

    // 获取曝光时间单位和值
    // 使用传输FD读取相机参数
    int unit = VsyCam_ReadCameraParam(m_controlId, TIME_UNIT);
    quint64 exposureValue = VsyCam_ReadCameraParam(m_controlId, TIME);
    quint64 exposureNs;

    // 根据单位转换为纳秒
    switch(unit) {
        case 0: // 纳秒
            exposureNs = exposureValue;
            break;
        case 1: // 微秒
            exposureNs = exposureValue * 1000;
            break;
        case 2: // 毫秒
            exposureNs = exposureValue * 1000000;
            break;
        case 3: // 秒
            exposureNs = exposureValue * 1000000000;
            break;
        default:
            qWarning() << "Unknown exposure unit:" << unit << " for device:" << m_deviceIp;
            return -1;
    }

    return exposureNs;
}

/**
 * @brief 获取图像像素尺寸
 * @return QSize对象，包含宽度和高度，失败返回空QSize
 */
int VisiyunDevice::getFirmwareVersion() const
{
    if (!m_isConnected || m_controlId <= 0) {
        return -1;
    }
    return VsyCam_ReadCameraParam(m_controlId,FIRMWARE_VERSION);//相机固件版本;
}

QSize VisiyunDevice::getPixelSize() const
{
    if (!m_isConnected || m_controlId <= 0) {
        qWarning() << "Device not connected:" << m_deviceIp;
        return QSize();
    }

    // 获取像素宽度和高度
    int width = VsyCam_ReadCameraParam(m_controlId, WIDTH);
    int height = VsyCam_ReadCameraParam(m_controlId, HEIGHT);

    if (width <= 0 || height <= 0) {
        qWarning() << "Invalid pixel size for device:" << m_deviceIp << "(" << width << "," << height << ")";
        return QSize();
    }

    return QSize(width, height);
}

/**
 * @brief 获取设备增益值
 * @return 增益值，失败返回-1
 */
quint64 VisiyunDevice::getGain() const
{
    if (!m_isConnected || m_controlId <= 0) {
        qWarning() << "Device not connected:" << m_deviceIp;
        return -1;
    }

    // 读取增益参数
    int gainValue = VsyCam_ReadCameraParam(m_controlId, GAIN);
    if (gainValue < 0) {
        qWarning() << "Failed to read gain value for device:" << m_deviceIp;
        return -1;
    }

    // 假设增益值是整数形式，需要转换为实际增益值
    return static_cast<quint64>(gainValue);
}

/**
 * @brief 设置设备增益值
 * @param gain 增益值
 * @return 操作结果，0表示成功，其他表示失败
 */
int VisiyunDevice::setGain(quint64 gain)
{
    if (!m_isConnected || m_controlId <= 0) {
        qWarning() << "Device not connected:" << m_deviceIp;
        return -1;
    }

    // 检查增益值是否在有效范围内
    if (gain < m_minGain || gain > m_maxGain) {
        qWarning() << "Gain value out of range (" << m_minGain << "-" << m_maxGain << ") for device:" << m_deviceIp;
        return -2;
    }

    // 将quint64类型的增益值转换为整数形式
    int gainValue = static_cast<int>(gain);
    int result = VsyCam_UpdateCameraParam(m_controlId, GAIN, gainValue,nullptr);
    if (result != VsyCam_SUCCESS) {
        qWarning() << "Failed to set gain value for device:" << m_deviceIp;
        return -1;
    }

    return 0;
}

/**
 * @brief 获取设备采样频率
 * @return 采样频率值(Hz)，失败返回-1
 */
quint64 VisiyunDevice::getSamplingFrequency() const
{
    if (!m_isConnected || m_controlId <= 0) {
        qWarning() << "Device not connected:" << m_deviceIp;
        return -1;
    }

    // 读取采样频率参数
    int frequencyValue = VsyCam_ReadCameraParam(m_controlId, FREQ);
    if (frequencyValue < 0) {
        qWarning() << "Failed to read sampling frequency for device:" << m_deviceIp;
        return -1;
    }

    // 假设采样频率是以Hz为单位的整数值
    return static_cast<quint64>(frequencyValue);
}

/**
 * @brief 设置设备采样频率
 * @param frequency 采样频率值(Hz)
 * @return 操作结果，0表示成功，其他表示失败
 */
int VisiyunDevice::setSamplingFrequency(quint64 frequency)
{
    if (!m_isConnected || m_controlId <= 0) {
        qWarning() << "Device not connected:" << m_deviceIp;
        return -1;
    }

    // 检查采样频率是否在有效范围内
    if (frequency < m_minFrequency || frequency > m_maxFrequency) {
        qWarning() << "Sampling frequency out of range (" << m_minFrequency << "-" << m_maxFrequency << ") Hz for device:" << m_deviceIp;
        return -2;
    }

    // 将quint64类型的频率值转换为整数形式
    int frequencyValue = static_cast<int>(frequency);
    int result = VsyCam_UpdateCameraParam(m_controlId, FREQ, frequencyValue,nullptr);
    if (result != VsyCam_SUCCESS) {
        qWarning() << "Failed to set sampling frequency for device:" << m_deviceIp;
        return -1;
    }

    return 0;
}

/**
 * @brief 设置设备曝光时间
 * @param time 曝光时间值(纳秒)
 * @return 操作结果，0表示成功，其他表示失败
 */
int VisiyunDevice::setExposureTime(quint64 time)
{
    if (!m_isConnected || m_controlId <= 0) {
        qWarning() << "Device not connected:" << m_deviceIp;
        return -1;
    }

    // 检查曝光时间是否在有效范围内
    if (time < m_minExposureTime || time > m_maxExposureTime) {
        qWarning() << "Exposure time out of range (" << m_minExposureTime << "-" << m_maxExposureTime << ") ns for device:" << m_deviceIp;
        return -2;
    }

    // 先获取当前时间单位
    int unit = VsyCam_ReadCameraParam(m_controlId, TIME_UNIT);
    int timeValue;

    // 根据单位将纳秒转换为相应单位的值
    switch(unit) {
        case 0: // 纳秒
            timeValue = static_cast<int>(time);
            break;
        case 1: // 微秒
            timeValue = static_cast<int>(time / 1000);
            break;
        case 2: // 毫秒
            timeValue = static_cast<int>(time / 1000000);
            break;
        case 3: // 秒
            timeValue = static_cast<int>(time / 1000000000);
            break;
        default:
            qWarning() << "Unknown exposure unit:" << unit << " for device:" << m_deviceIp;
            return -1;
    }

    int result = VsyCam_UpdateCameraParam(m_controlId, TIME, timeValue,nullptr);
    if (result != VsyCam_SUCCESS) {
        qWarning() << "Failed to set exposure time for device:" << m_deviceIp;
        return -1;
    }

    return 0;
}

/**
 * @brief 获取设备触发模式
 * @return 触发模式(0:内触发, 1:外触发)，失败返回-1
 */
int VisiyunDevice::getTriggerMode() const
{
    if (!m_isConnected || m_controlId <= 0) {
        qWarning() << "Device not connected:" << m_deviceIp;
        return -1;
    }
    // 返回当前缓存的触发模式（四种模式）
    return m_TriggerMode;
}

/**
 * @brief 设置设备触发模式
 * @param mode 触发模式(0:连续采集, 1:单次外触发, 2:连续外触发, 3:内触发)
 * @return 操作结果，0表示成功，其他表示失败
 */
int VisiyunDevice::setTriggerMode(int mode)
{
    if (m_controlId <= 0) {
        qWarning() << "Device not connected:" << m_deviceIp;
        return -1;
    }

    int result = VsyCam_SUCCESS;
    if (mode == TRIGGER_MODE_INTERNAL||mode == TRIGGER_MODE_EXTERNAL_SINGLE || mode == TRIGGER_MODE_EXTERNAL_CONTINUOUS) {
        // 外触发（设置为外同步，具体单次/连续由采集控制决定）
        result = VsyCam_UpdateCameraParam(m_controlId, SYNC, m_ExternalTriggerChannel, nullptr);
    } else if (mode == TRIGGER_MODE_CONTINUOUS) {
        // 连续采集（自由运行）。此处默认设为0，如设备有不同值，请调整。
        result = VsyCam_UpdateCameraParam(m_controlId, SYNC, 0, nullptr);
    } else {
        qWarning() << "Unknown trigger mode:" << mode << " for device:" << m_deviceIp;
        return -1;
    }

    if (result != VsyCam_SUCCESS) {
        qWarning() << "Failed to update SYNC for device:" << m_deviceIp << ", ret=" << result;
        return result;
    }

    m_TriggerMode = mode;
    return 0;
}

/**
 * @brief 获取设备触发沿类型
 * @return 触发沿类型(0:上升沿, 1:下降沿)，失败返回-1
 */
int VisiyunDevice::getTriggerEdge() const
{
    if (!m_isConnected || m_controlId <= 0) {
        qWarning() << "Device not connected:" << m_deviceIp;
        return -1;
    }
    // 返回当前缓存的触发沿类型
    return !m_TriggerEdgeType;
}

/**
 * @brief 设置设备触发沿类型
 * @param edge 触发沿类型(0:上升沿, 1:下降沿)
 * @return 操作结果，0表示成功，其他表示失败
 */
int VisiyunDevice::setTriggerEdge(int edge)
{
    if (!m_isConnected || m_controlId <= 0) {
        qWarning() << "Device not connected:" << m_deviceIp;
        return -1;
    }

    // 验证触发沿类型是否有效
    if (edge != 0 && edge != 1) {
        qWarning() << "Invalid trigger edge type:" << edge << " for device:" << m_deviceIp;
        return -2;
    }
    int result = VsyCam_UpdateCameraParam(m_controlId, WAY_TRIG, !edge, nullptr);
    if (result != VsyCam_SUCCESS) {
        qWarning() << "Failed to set trigger edge type for device:" << m_deviceIp;
        return -1;
    }

    m_TriggerEdgeType = edge;
    qInfo() << "Trigger edge type set to" << edge << "for device:" << m_deviceIp;
    return 0;
}

/**
 * @brief 获取设备触发通道
 * @return 触发通道号，失败返回-1
 */
int VisiyunDevice::getTriggerChannel() const
{
    if (!m_isConnected || m_controlId <= 0) {
        qWarning() << "Device not connected:" << m_deviceIp;
        return -1;
    }
    // 返回当前缓存的触发通道号
    return m_ExternalTriggerChannel;
}

/**
 * @brief 设置设备触发通道
 * @param channel 触发通道号
 * @return 操作结果，0表示成功，其他表示失败
 */
int VisiyunDevice::setTriggerChannel(int channel)
{
    if (!m_isConnected || m_controlId <= 0) {
        qWarning() << "Device not connected:" << m_deviceIp;
        return -1;
    }

    // 验证触发通道号是否有效（假设通道号从1开始）
    if (channel < 1||channel>2) {
        qWarning() << "Invalid trigger channel:" << channel << " for device:" << m_deviceIp;
        return -2;
    }
    // 保存新的触发通道号
    m_ExternalTriggerChannel = channel;
    
    // 如果当前是外触发模式，需要更新同步参数
    if (m_TriggerMode == TRIGGER_MODE_EXTERNAL_SINGLE || m_TriggerMode == TRIGGER_MODE_EXTERNAL_CONTINUOUS) {
        int result = VsyCam_UpdateCameraParam(m_controlId, SYNC, channel, nullptr);
        if (result != VsyCam_SUCCESS) {
            qWarning() << "Failed to update trigger channel for device:" << m_deviceIp;
            return -1;
        }
    }
    
    qInfo() << "Trigger channel set to" << channel << "for device:" << m_deviceIp;
    return 0;
}

/**
 * @brief 初始化设备参数范围和单位
 * @return 成功返回true，失败返回false
 */
bool VisiyunDevice::initializeDeviceParameters()
{
    if (!m_isConnected || m_controlId <= 0) {
        qWarning() << "Device not connected when initializing parameters:" << m_deviceIp;
        return false;
    }

    // 获取曝光时间单位
    m_timeUnit = VsyCam_ReadCameraParam(m_controlId, TIME_UNIT);
    if (m_timeUnit < 0) {
        qWarning() << "Failed to read time unit for device:" << m_deviceIp;
        m_timeUnit = 0; // 默认使用纳秒
    }

    // 从设备获取增益单位
    m_gainUnit = VsyCam_ReadCameraParam(m_controlId, GAIN_UNIT);
    if (m_gainUnit < 0) {
        qWarning() << "Failed to read gain unit for device:" << m_deviceIp;
        m_gainUnit = 0; // 默认值
    }
    
    // 从设备获取采样频率单位
    m_frequencyUnit = VsyCam_ReadCameraParam(m_controlId, FREQ_UNIT);
    if (m_frequencyUnit < 0) {
        qWarning() << "Failed to read frequency unit for device:" << m_deviceIp;
        m_frequencyUnit = 0; // 默认值
    }

    // 从设备获取增益范围
    int minGainValue = VsyCam_ReadCameraParam(m_controlId, MIN_GAIN);
    int maxGainValue = VsyCam_ReadCameraParam(m_controlId, MAX_GAIN);
    if (minGainValue < 0 || maxGainValue < 0 || minGainValue > maxGainValue) {
        qWarning() << "Failed to read gain range for device:" << m_deviceIp;
        m_minGain = 0.0;
        m_maxGain = 100.0;
    } else {
        m_minGain = static_cast<quint64>(minGainValue);
        m_maxGain = static_cast<quint64>(maxGainValue);
    }

    // 从设备获取采样频率范围
    int minFreqValue = VsyCam_ReadCameraParam(m_controlId, MIN_FREQ);
    int maxFreqValue = VsyCam_ReadCameraParam(m_controlId, MAX_FREQ);
    if (minFreqValue < 0 || maxFreqValue < 0 || minFreqValue > maxFreqValue) {
        qWarning() << "Failed to read frequency range for device:" << m_deviceIp;
        m_minFrequency = 1.0;
        m_maxFrequency = 10000.0;
    } else {
        m_minFrequency = static_cast<quint64>(minFreqValue);
        m_maxFrequency = static_cast<quint64>(maxFreqValue);
    }

    // 从设备获取曝光时间范围
    int minTimeValue = VsyCam_ReadCameraParam(m_controlId, MIN_TIME);
    int maxTimeValue = VsyCam_ReadCameraParam(m_controlId, MAX_TIME);
    if (minTimeValue < 0 || maxTimeValue < 0 || minTimeValue > maxTimeValue) {
        qWarning() << "Failed to read exposure time range for device:" << m_deviceIp;
        m_minExposureTime = 1;
        m_maxExposureTime = 1000000000;
    } else {
        // 根据当前时间单位将设备返回的值转换为纳秒
        quint64 unitMultiplier = 1;
        switch(m_timeUnit) {
            case 0: unitMultiplier = 1; break;             // 纳秒
            case 1: unitMultiplier = 1000; break;          // 微秒
            case 2: unitMultiplier = 1000000; break;       // 毫秒
            case 3: unitMultiplier = 1000000000; break;    // 秒
            default: unitMultiplier = 1; break;            // 默认纳秒
        }
        m_minExposureTime = static_cast<quint64>(minTimeValue) * unitMultiplier;
        m_maxExposureTime = static_cast<quint64>(maxTimeValue) * unitMultiplier;
    }
    m_TriggerEdgeType = VsyCam_ReadCameraParam(m_controlId, WAY_TRIG);
    // 记录参数初始化信息
    qInfo() << "Device parameters initialized for:" << m_deviceIp
            << " Time unit:" << m_timeUnit
            << " Gain unit:" << m_gainUnit
            << " Frequency unit:" << m_frequencyUnit
            << " Gain range:" << m_minGain << "-" << m_maxGain
            << " Frequency range:" << m_minFrequency << "-" << m_maxFrequency << " Hz"
            << " Exposure range:" << m_minExposureTime << "-" << m_maxExposureTime << " ns";

    return true;
}

void VisiyunDevice::sendBeatheart()
{
    if (m_controlId <= 0) {
        return;
    }
    VsyCam_UpdateCameraParam(m_controlId,HEART_BEAT,0,NULL);
}

/**
 * @brief 获取设备参数
 * @return 设备参数映射，使用QVariantMap作为万能变量类型
 */
QVariantMap VisiyunDevice::getParameters() const
{
    QVariantMap params;
    
    // 获取所有设备参数（不包括单位参数）
    params[PARAM_GAIN] = getGain();
    params[PARAM_SAMPLING_FREQUENCY] = getSamplingFrequency();
    params[PARAM_EXPOSURE_TIME] = getExposureTime();
    params[PARAM_TRIGGER_MODE] = getTriggerMode();
    params[PARAM_TRIGGER_EDGE] = getTriggerEdge();
    params[PARAM_TRIGGER_CHANNEL] = getTriggerChannel();
    
    return params;
}

/**
 * @brief 设置设备参数
 * @param params 设备参数映射，使用QVariantMap作为万能变量类型
 * @return 设置成功返回true，失败返回false
 */
bool VisiyunDevice::setParameters(const QVariantMap& params)
{
    bool result = true;
    
    // 检查并设置增益
    if (params.contains(PARAM_GAIN)) {
        quint64 gain = params[PARAM_GAIN].toULongLong();
        if (setGain(gain) != 0) {
            result = false;
        }
    }
    
    // 检查并设置采样频率
    if (params.contains(PARAM_SAMPLING_FREQUENCY)) {
        quint64 frequency = params[PARAM_SAMPLING_FREQUENCY].toULongLong();
        if (setSamplingFrequency(frequency) != 0) {
            result = false;
        }
    }
    
    // 检查并设置曝光时间
    if (params.contains(PARAM_EXPOSURE_TIME)) {
        quint64 exposureTime = params[PARAM_EXPOSURE_TIME].toULongLong();
        if (setExposureTime(exposureTime) != 0) {
            result = false;
        }
    }
    
    // 检查并设置触发模式
    if (params.contains(PARAM_TRIGGER_MODE)) {
        int triggerMode = params[PARAM_TRIGGER_MODE].toInt();
        if (setTriggerMode(triggerMode) != 0) {
            result = false;
        }
    }
    
    // 检查并设置触发沿类型
    if (params.contains(PARAM_TRIGGER_EDGE)) {
        int triggerEdge = params[PARAM_TRIGGER_EDGE].toInt();
        if (setTriggerEdge(triggerEdge) != 0) {
            result = false;
        }
    }
    
    // 检查并设置触发通道
    if (params.contains(PARAM_TRIGGER_CHANNEL)) {
        int triggerChannel = params[PARAM_TRIGGER_CHANNEL].toInt();
        if (setTriggerChannel(triggerChannel) != 0) {
            result = false;
        }
    }
    
    return result;
}
